/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ds_semetralka;

import entities.Faculty;
import entities.Professor;
import entities.Student;
import entities.Subject;
import java.util.List;
import javax.persistence.LockModeType;
import javax.persistence.OptimisticLockException;

import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 *
 * @author Admin
 */
public class StudentInterface extends Interface {

    private Student student;

    public StudentInterface() {
        emf = Persistence.createEntityManagerFactory("persistence");
        em = emf.createEntityManager();
        tx = em.getTransaction();
    }

    public StudentInterface(Long studentId) {
        emf = Persistence.createEntityManagerFactory("persistence");
        em = emf.createEntityManager();
        tx = em.getTransaction();
        this.student = em.find(Student.class, studentId);
    }

    public boolean setStudent(Long id) {
        this.student = em.find(Student.class, id);

        if (student == null) {
            return false;
        }

        return true;
    }

    public Student getStudent() {
        return student;
    }

    @Override
    public List<Subject> getAllSubjects() {
        Query q = em.createNamedQuery("Subject.findAll");

        return q.getResultList();
    }

    public List<Subject> getStudentsSubjects() {
        return student.getSubjects();
    }

    @Override
    public List<Subject> getSubjectsFromFaculty(Faculty faculty) {
        Query q = em.createNamedQuery("Subject.findByFaculty");

        q.setParameter("faculty", faculty);

        return q.getResultList();
    }

    public List<Subject> getProfessorsSubjects(Professor professor) {
        Query q = em.createNamedQuery("Subject.findbySupervisor");

        q.setParameter("supervisor", professor);

        return q.getResultList();
    }

    public List<Subject> getProfessorsSubjects(Long professorId) {
        Query q = em.createNamedQuery("Subject.findBySupervisor");
        Professor professor = em.find(Professor.class, professorId);

        if (professor == null) {
            System.out.println("Profesor neexistuje.");
            return null;
        }

        q.setParameter("supervisor", professor);

        return q.getResultList();
    }

    public List<Professor> getAllProfessors() {
        Query q = em.createNamedQuery("Professor.findAll");

        return q.getResultList();
    }

    public List<Subject> getSubjectsFromFaculty(Long facultyId) {
        Query q = em.createNamedQuery("Subject.findByFaculty");
        Faculty faculty = em.find(Faculty.class, facultyId);

        if (faculty == null) {
            System.out.println("Faculty does not exist");
            return null;
        }

        q.setParameter("faculty", faculty);

        return q.getResultList();
    }

    @Override
    public List<Faculty> getAllFaculties() {
        Query q = em.createNamedQuery("Faculty.findAll");

        return q.getResultList();
    }

    public Subject getSubject(Long subjectId) {
        Subject subject = em.find(Subject.class, subjectId);

        if (subject == null) {
            System.out.println("Subject does not exist.");
            return null;
        }

        return subject;
    }

    public void addSubject(Long subjectId) {
        try {
            tx.begin();
            Subject subject = em.find(Subject.class, subjectId, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

            if (subject == null) {
                System.out.println("Subject does not exist.");
                return;
            }

            if (subject.getStudents().size() < subject.getMaxStudents()) {
                if (!subject.getStudents().contains(student)) {

                    student.addSubject(subject);
                    subject.addStudent(student);
                    System.out.println("Student " + student + " has just signed to " + subject);
                    em.persist(student);
                    em.persist(subject);
         
                } else {
                    System.out.println("Already signed to this subject.");
                    tx.rollback();
                    return;
                }
            } else {
                System.out.println("Subject is full.");
                tx.rollback();
                return;
            }
            tx.commit();
        } catch (OptimisticLockException ex) {
            System.out.println("Trying to add locked subject");
            tx.rollback();
        }
    }

    public void removeSubject(Long subjectId) {
        try {
            tx.begin();
            Subject subject = em.find(Subject.class, subjectId, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

            if (subject == null) {
                System.out.println("Subject does not exist.");
                return;
            }

            if (student.getSubjects().contains(subject)) {

                student.removeSubject(subject);
                subject.removeStudent(student);
                System.out.println("Student " + student + " has just canceled " + subject);
                em.persist(student);
                em.persist(subject);
                
            } else {
                System.out.println("Subject already deleted.");
                tx.rollback();
                return;
            }
            tx.commit();
        } catch (OptimisticLockException ex) {
            System.out.println("Trying to remove locked subject.");
            tx.rollback();
        }
    }
}
